﻿#include "imageviewer.h"
#include "ui_imageviewer.h"
#include <QClipboard>
#include <QDesktopWidget>
#include <QFileDialog>
#include <QImageWriter>
#include <QMessageBox>
#include <QResizeEvent>
#include <QScreen>
#include <QScrollBar>
#include <QStandardPaths>
#include <QToolTip>
#include "characterset.h"

ImageViewer::ImageViewer(QWidget *parent) :
    QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint),
    ui(new Ui::ImageViewer), scaleFactor(1.0)
{
    ui->setupUi(this);
    ui->label_image->setBackgroundRole(QPalette::Base);
    ui->scrollArea->setBackgroundRole(QPalette::Dark);
    ui->toolBar->setWindowOpacity(0.6);
}

ImageViewer::~ImageViewer()
{
    delete ui;
}

void ImageViewer::setImage(const QImage &image)
{
    setPixmap(QPixmap::fromImage(image));
}

void ImageViewer::setPixmap(const QPixmap &pixmap)
{
    ui->label_image->setPixmap(pixmap);
    ui->label_image->setFixedSize(pixmap.size());
    ui->button_normal->setEnabled(false);
    setProperSize(pixmap.size());
}

void ImageViewer::setProperSize(const QSize &imageSize)
{
    auto offsetSize = QSize(frameGeometry().width() - geometry().width(), frameGeometry().height() - geometry().height() + ui->toolBar->minimumSizeHint().height());
    auto framedSize = imageSize + offsetSize;
    if(framedSize.width() < 400 + offsetSize.width())
        framedSize.setWidth(400 + offsetSize.width());
    if(framedSize.height() < 300 + offsetSize.height())
        framedSize.setHeight(300 + offsetSize.height());

    auto screen = QApplication::screens().value(QApplication::desktop()->screenNumber(this), QApplication::primaryScreen());
    auto availableGeometry = screen->availableGeometry();
    if(framedSize.width() > availableGeometry.width())
        framedSize.setWidth(availableGeometry.width());
    if(framedSize.height() > availableGeometry.height())
        framedSize.setHeight(availableGeometry.height());
    QRect rt(0, 0, framedSize.width(), framedSize.height());
    rt.moveCenter(availableGeometry.center());
    move(rt.topLeft());
    resize(framedSize - offsetSize);
}

static void adjustScrollBar(QScrollBar *scrollBar, double factor)
{
    scrollBar->setValue(int(factor * scrollBar->value()
                                  + ((factor - 1) * scrollBar->pageStep()/2)));
}

void ImageViewer::scaleImage(double factor)
{
    scaleFactor *= factor;
    ui->label_image->setFixedSize(scaleFactor * ui->label_image->pixmap()->size());

    adjustScrollBar(ui->scrollArea->horizontalScrollBar(), factor);
    adjustScrollBar(ui->scrollArea->verticalScrollBar(), factor);

    ui->button_zoomin->setEnabled(scaleFactor < 3.0);
    ui->button_zoomout->setEnabled(scaleFactor > 0.333);
    ui->button_normal->setEnabled(scaleFactor != 1.0);
    ui->label_zoom->setText(QString::number(int(scaleFactor  * 100))+'%');
}

bool ImageViewer::saveFile(const QString &fileName)
{
    QImageWriter writer(fileName);

    if (!writer.write(ui->label_image->pixmap()->toImage())) {
        QMessageBox::information(this, QGuiApplication::applicationDisplayName(),
                                 trECSUTF8("无法保存到%1: %2")
                                 .arg(QDir::toNativeSeparators(fileName)), writer.errorString());
        return false;
    }
    return true;
}

void ImageViewer::on_button_zoomin_clicked()
{
    scaleImage(1.25);
}

void ImageViewer::on_button_zoomout_clicked()
{
    scaleImage(0.8);
}

void ImageViewer::on_button_normal_clicked()
{
    scaleImage(1.0 / scaleFactor);
}

void ImageViewer::on_button_copy_clicked()
{
    if(auto pixmap = ui->label_image->pixmap())
    {
        if(!pixmap->isNull())
        {
            QGuiApplication::clipboard()->setPixmap(*pixmap);
            QToolTip::showText(ui->button_copy->mapToGlobal(QPoint(0,0)), trECSUTF8("已复制到剪切板"), ui->button_copy);
        }
    }
}

void ImageViewer::on_button_saveas_clicked()
{
    QFileDialog dialog(this, trECSUTF8("另存为"));
    dialog.setDirectory(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
    auto supportedMimeTypes = QImageWriter::supportedMimeTypes();
    QStringList mimeTypeFilters;
    foreach (const QByteArray &mimeTypeName, supportedMimeTypes)
        mimeTypeFilters.append(mimeTypeName);
    mimeTypeFilters.sort();

    dialog.setAcceptMode(QFileDialog::AcceptSave);
    dialog.setMimeTypeFilters(mimeTypeFilters);
    dialog.selectMimeTypeFilter("image/png");
    dialog.setDefaultSuffix("png");

    while (dialog.exec() == QDialog::Accepted && !saveFile(dialog.selectedFiles().first())) {}
}
